const std = @import("std");

/// 池化分配器 - 用于固定大小对象
pub fn PoolAllocator(comptime T: type, comptime pool_size: usize) type {
    return struct {
        const Self = @This();
        
        pool: [pool_size]T,
        used: [pool_size]bool,
        mutex: std.Thread.Mutex,
        
        pub fn init() Self {
            return .{
                .pool = undefined,
                .used = [_]bool{false} ** pool_size,
                .mutex = .{},
            };
        }
        
        pub fn alloc(self: *Self) ?*T {
            self.mutex.lock();
            defer self.mutex.unlock();
            
            for (&self.used, 0..) |*is_used, i| {
                if (!is_used.*) {
                    is_used.* = true;
                    return &self.pool[i];
                }
            }
            return null;
        }
        
        pub fn free(self: *Self, ptr: *T) void {
            self.mutex.lock();
            defer self.mutex.unlock();
            
            const index = (@intFromPtr(ptr) - @intFromPtr(&self.pool[0])) / @sizeOf(T);
            if (index < pool_size) {
                self.used[index] = false;
            }
        }
        
        pub fn reset(self: *Self) void {
            self.mutex.lock();
            defer self.mutex.unlock();
            
            for (&self.used) |*is_used| {
                is_used.* = false;
            }
        }
    };
}

test "pool allocator" {
    const testing = std.testing;
    
    var pool = PoolAllocator(u32, 10).init();
    
    const ptr1 = pool.alloc();
    try testing.expect(ptr1 != null);
    
    const ptr2 = pool.alloc();
    try testing.expect(ptr2 != null);
    try testing.expect(ptr1 != ptr2);
    
    pool.free(ptr1.?);
    
    const ptr3 = pool.alloc();
    try testing.expect(ptr3 == ptr1);
}
